import { Scene } from '@babylonjs/core/scene';
import { AbstractGroup, IAbstractGroupOptions } from './abstract-group';
import { CreateHandleTo, IHandle } from '../../data/data-handle';
import { IUIRectangleOptions, UIRectangle } from './ui-rectangle';
import { Rectangle } from '@babylonjs/gui/2D/controls/rectangle';
import { MAX_FLOAT } from '../../tool/calculation';


/**
 * 拾色器控件参数对象
 * @param color 当前所选颜色值
 */
interface IUIColorPickerOptions extends IAbstractGroupOptions<IUIRectangleOptions> {
    color?: string,
}


/**
 * 拾色器控件
 * @param name 名称
 * @param scene 所在场景
 * @param options 参数对象
 */
class UIColorPicker extends AbstractGroup {

    private _selectedColor!: string;
    private _curItem: UIRectangle | undefined;

    constructor(name: string, scene: Scene, options?: IUIColorPickerOptions) {
        super(name, scene, options);
    }

    /**
     * 设置当前颜色值
     */
    public set color(color: string) {
        const change = this.isChange(color);
        if (!change) return;
        for (const item of this.items) {
            this.match(item as UIRectangle);
        }
        if (!this.avoidEventHandle) this.changeHandles.forEach(handle => handle.callback(this._selectedColor));
    }

    /**
     * 获取当前颜色值
     */
    public get color(): string {
        return this._selectedColor;
    }

    public onChange(func: (color: string) => void): IHandle<string> {
        return CreateHandleTo(func, this.changeHandles);
    }

    protected generateItem(name: string, scene: Scene, itemOptions: IUIRectangleOptions, groupOptions: IUIColorPickerOptions): UIRectangle {
        if (!this._selectedColor) {
            this._selectedColor = groupOptions.color || '#000000';
        }

        let s = 1;
        if (itemOptions.width && itemOptions.height) {
            s = Math.min(itemOptions.width, itemOptions.height);
        } else if (itemOptions.width) {
            s = itemOptions.width;
        } else if (itemOptions.height) {
            s = itemOptions.height;
        }
        itemOptions.width = s;
        itemOptions.height = s;

        const rect = new UIRectangle(name, scene, itemOptions);
        this.match(rect);

        rect.control.onPointerClickObservable.add(() => {
            const change = this.isChange((rect.control as Rectangle).background);
            if (!change) return;
            this.match(rect);
            if (!this.avoidEventHandle) this.changeHandles.forEach(handle => handle.callback(this._selectedColor));
        });

        return rect;
    }

    /**
     * 检测颜色值是否改变，并更新成员控件样式
     * @param color 颜色值
     * @returns 是否改变
     */
    private isChange(color: string): boolean {
        if (this._curItem) {
            if ((this._curItem.control as Rectangle).background !== color) {
                this._selectedColor = color;
                (this._curItem.control as Rectangle).cornerRadius = MAX_FLOAT;
                return true;
            } else {
                return false;
            }
        }
        return this._selectedColor !== color;
    }

    /**
     * 检测成员控件并改变其样式
     * @param item 成员控件
     * @returns 是否匹配成功
     */
    private match(item: UIRectangle): boolean {
        if (this._selectedColor === (item.control as Rectangle).background) {
            this._curItem = item;
            (item.control as Rectangle).cornerRadius = 0;
            return true;
        } else {
            (item.control as Rectangle).cornerRadius = MAX_FLOAT;
            return false;
        }
    }

}


/**
 * 创建拾色器控件
 * @param name 名称
 * @param scene 所在场景
 * @param options 参数对象
 * @param changeCallback 值改变时的回调函数
 * @returns 拾色器控件
 */
const CreateUIColorPicker = (name: string, scene: Scene, options: IUIColorPickerOptions, changeCallback?: { (color: string): void }): UIColorPicker => {
    const cp = new UIColorPicker(name, scene, options);
    if (changeCallback) cp.onChange(changeCallback);
    return cp;
};


export { UIColorPicker, CreateUIColorPicker };
export type { IUIColorPickerOptions };